package com.shiroha.account.controller;

import com.shiroha.account.pojo.dto.PasswordDTO;
import com.shiroha.common.utils.Result;
import com.shiroha.account.mapstruct.UserMapper;
import com.shiroha.common.pojo.dto.UserDTO;
import com.shiroha.account.pojo.vo.UserVO;
import com.shiroha.account.service.IAccountService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.keycloak.representations.AccessTokenResponse;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/as/account")
@AllArgsConstructor
@Slf4j
public class AccountController {

    private final IAccountService userService;

    /**
     * 客户端凭证授权模式登录.
     * <p>在这种模式下，用户不需要与 Keycloak 进行交互，客户端可以直接获取访问令牌</p>
     * <p>需要注意的是，这种方法的安全性低于授权码模式。
     * 用户密码以明文形式传播，因此建议在无浏览器的单点登录场景中使用此方法.</p>
     *
     * @param user 请求体
     * @return 访问令牌
     */
    @PostMapping("/login")
    public AccessTokenResponse login(@RequestBody UserVO user) {
        return userService.loginByPassword(user.getUsername(), user.getPassword());
    }

    /**
     * 刷新token
     * @param jwt jwt认证对象
     * @param refreshToken refresh_token
     * @return 刷新后的token
     */
    @PostMapping("/token/refresh")
    public AccessTokenResponse refreshToken(@AuthenticationPrincipal Jwt jwt, @RequestBody String refreshToken) {
        return userService.refreshAccessToken(refreshToken);
    }

    /**
     * 用户注册，通过 Keycloak API创建新用户
     * @param user 请求体，包含注册信息
     * @return 注册成功的消息
     */
    @PostMapping("/register")
    public Result<String> register(@RequestBody UserVO user) {
        UserDTO userDTO = UserMapper.INSTANCE.userVOToUserDTO(user);
        userDTO = userService.createUser(userDTO);
        return Result.success("注册成功", userDTO.getId());
    }

    /**
     * 无状态登出，配合 Jwt 使用场景，需要在请求头中携带 Bearer Token
     * @param jwt Jwt认证对象
     * @return 用户ID
     */
    @GetMapping("/logout")
    public Result<String> logout(@AuthenticationPrincipal Jwt jwt) {
        userService.logout(jwt.getSubject());
        return Result.success("登出成功", jwt.getSubject());
    }

    /**
     * 获取用户个人信息
     * @param jwt 认证对象
     * @return 用户信息 DTO
     */
    @GetMapping("/info")
    public Result<UserVO> getUserInfo(@AuthenticationPrincipal Jwt jwt) {
        UserVO userVO = UserMapper.INSTANCE.userDTOToUserVO(userService.getUserById(jwt.getSubject()));
        return Result.success(userVO);
    }

    /**
     * 修改个人用户信息
     * @param jwt 认证对象
     * @param userVO VO对象
     * @return 用户ID
     */
    @PutMapping("/info")
    public Result<String> updateUserInfo(@AuthenticationPrincipal Jwt jwt, @RequestBody UserVO userVO) {
        userService.updateUser(jwt.getSubject(), UserMapper.INSTANCE.userVOToUserDTO(userVO));
        return Result.success("更新成功", userVO.getId());
    }

    /**
     * 修改账户密码
     * @param jwt 认证对象
     * @param passwordDTO 密码 DTO 对象
     * @return 用户ID
     */
    @PutMapping("/password")
    public Result<String> updatePassword(@AuthenticationPrincipal Jwt jwt, @RequestBody PasswordDTO passwordDTO) {
        userService.updatePassword(jwt.getSubject(), passwordDTO);
        return Result.success("密码修改成功", jwt.getSubject());
    }
}
